package com.renwen.sms.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.renwen.sms.dao.*;
import com.renwen.sms.dto.*;
import com.renwen.sms.entity.Course;
import com.renwen.sms.entity.Student;
import com.renwen.sms.entity.Teacher;
import com.renwen.sms.entity.XuanKe;
import com.renwen.sms.entity.Class;
import com.renwen.sms.exception.MyRuntimeException;
import com.renwen.sms.service.TeacherService;
import com.renwen.sms.util.Result;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 教师业务逻辑实现类
 *
 * @author zuo
 */
@Service
@Transactional
public class TeacherServiceImpl implements TeacherService {
    @Resource
    private StudentDao studentDao;
    @Resource
    private CourseDao courseDao;
    @Resource
    private ClassDao classDao;
    @Resource
    private TeacherDao teacherDao;
    @Resource
    private XuanKeDao xuanKeDao;

    /**
     * 分页查询管理员操作下所有教师信息
     *
     * @param page      页码
     * @param size      每页显示条数
     * @param searchMap 搜索条件
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public PageResult<TeacherDto> list(Integer page, Integer size, Map<String, Object> searchMap) {
        // 构建查询条件
        //搜索框模糊查询
        QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
        if (!ObjectUtil.hasEmpty(searchMap)) {
            if (!ObjectUtil.hasEmpty(searchMap.get("sex"))) {
                queryWrapper.eq("t_sex", searchMap.get("sex"));
            }
            if (!ObjectUtil.hasEmpty(searchMap.get("name"))) {
                queryWrapper.like("t_name", searchMap.get("name"));
            }
        }
        queryWrapper.select("t_no", "t_name", "t_sex", "id", "t_age", "entry_year", "t_pwd", "nick_name");
        // 根据编号降序排序
        queryWrapper.orderByDesc("t_no");

        Page<Teacher> teachers = teacherDao.selectPage(new Page<Teacher>(page, size), queryWrapper);
        List<TeacherDto> cds = new ArrayList<>();
        for (Teacher teacher : teachers.getRecords()) {
            TeacherDto teacherDto = new TeacherDto();
            BeanUtils.copyProperties(teacher, teacherDto);
            cds.add(teacherDto);
        }
        return new PageResult<TeacherDto>(cds, teachers.getTotal());
    }

    /**
     * 添加教师
     *
     * @param teacher
     */
    @Override
    public void save(Teacher teacher) {
        // 0. 验证学号
        if (!ReUtil.isMatch("\\d{10,15}$", teacher.getTNo())) {
            throw new MyRuntimeException("教师号不对！");
        }
        // 1. 验证密码
        if (!ReUtil.isMatch("^[0-9A-Za-z]\\d{4,15}$", teacher.getTPwd())) {
            throw new MyRuntimeException("密码格式不对！");
        }
        // 2. 验证姓名
        if (StrUtil.hasBlank(teacher.getTName())) {
            throw new MyRuntimeException("姓名不能为空！");
        }
        // 3. 验证性别
        if (StrUtil.hasBlank(teacher.getTSex())) {
            throw new MyRuntimeException("性别不能为空！");
        }
        // 4. 入学时间
        if (!ReUtil.isMatch("^20\\d{2}$", teacher.getEntryYear())) {
            throw new MyRuntimeException("入职时间格式不对！,为4位数年份");
        }
        // 5. 执行添加操作
        try {
            //设置默认昵称
            teacher.setNickName("Tom");
            teacherDao.insert(teacher);
        } catch (Exception e) {
            throw new MyRuntimeException("添加教师出错！" + e.getMessage());
        }
    }

    /**
     * 根据教师编号查询教师信息
     *
     * @param id 教师编号
     * @return 教师信息
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public Result get(Integer id) {
        if (!NumberUtil.isNumber(String.valueOf(id))) {
            throw new MyRuntimeException("编号应该是数字！");
        }
        try {
            Teacher teacher = teacherDao.selectById(id);
            TeacherDto teacherDto = new TeacherDto();
            BeanUtils.copyProperties(teacher, teacherDto);
            return new Result("查询成功", teacherDto);
        } catch (Exception e) {
            throw new MyRuntimeException("根据教师编号查询出错！" + e.getMessage());
        }
    }

    /**
     * 修改教师信息
     *
     * @param teacher 教师对象
     */
    @Override
    public void update(Teacher teacher) {
        // 0. 验证教师号
        if (!ReUtil.isMatch("\\d{10,15}$", teacher.getTNo())) {
            throw new MyRuntimeException("学号格式不对！");
        }
        // 1. 验证姓名
        if (StrUtil.hasBlank(teacher.getTName())) {
            throw new MyRuntimeException("姓名不能为空！");
        }
        // 2. 验证性别
        if (StrUtil.hasBlank(teacher.getTSex())) {
            throw new MyRuntimeException("性别不能为空！");
        }
        // 3. 入学时间
        if (!ReUtil.isMatch("^20\\d{2}$", teacher.getEntryYear())) {
            throw new MyRuntimeException("入职时间格式不对！,为4位数年份");
        }
        // 4. 执行修改操作
        try {
            teacherDao.updateById(teacher);
        } catch (Exception e) {
            throw new MyRuntimeException("修改教师信息出错！" + e.getMessage());
        }
    }

    /**
     * 根据教师号删除
     */
    @Override
    public void delete(String tNo) {
        Map<String, Object> map = new HashMap<>();
        map.put("t_no", tNo);
        try {
            teacherDao.deleteByMap(map);
        } catch (Exception e) {
            throw new MyRuntimeException("删除教师时出错！" + e.getMessage());
        }
    }

    /**
     * 批量删除教师信息
     *
     * @param ids 教师编号列表
     */
    @Override
    public void batchDelete(String ids) {
        //字符串切割
        String[] strs = ids.split(",");
        List<Integer> ids1 = new ArrayList<>();
        for (String str : strs) {
            ids1.add(Integer.valueOf(str));
        }
        if (ObjectUtil.hasEmpty(ids1)) {
            throw new MyRuntimeException("请先选择要删除的教师！");
        }
        try {
            teacherDao.deleteBatchIds(ids1);
        } catch (Exception e) {
            throw new MyRuntimeException("批量删除失败！" + e.getMessage());
        }
    }

    /**
     * 查询选择自己课程的学生信息：
     * 根据教师号查询选课信息
     *
     * @param page      页码
     * @param size      每页显示条数
     * @param searchMap 搜索条件
     * @return 课程表信息
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public PageResult<XuanKeDto> studentList(Integer page, Integer size, Map<String, Object> searchMap) {
        QueryWrapper<XuanKe> xuanKeQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Class> classQueryWrapper = new QueryWrapper<>();
        // 构建查询条件
        //搜索框模糊查询
        if (!ObjectUtil.hasEmpty(searchMap)) {
            if (!ObjectUtil.hasEmpty(searchMap.get("tNo"))) {
                xuanKeQueryWrapper.eq("t_no", searchMap.get("tNo"));
                //查询选课表字段
                xuanKeQueryWrapper.select("c_no", "s_no", "c_grade", "id", "t_no");
                // 根据id降序排序
                xuanKeQueryWrapper.orderByDesc("c_no");
                Page<XuanKe> xuanKes = xuanKeDao.selectPage(new Page<XuanKe>(page, size), xuanKeQueryWrapper);
                List<XuanKeDto> cds = new ArrayList<>();
                XuanKeDto xuanKeDto = new XuanKeDto();
                //遍历当前教师所教学生的选课信息
                for (XuanKe xuanKe : xuanKes.getRecords()) {

                    studentQueryWrapper.eq("s_no", xuanKe.getSNo());
                    courseQueryWrapper.eq("c_no", xuanKe.getCNo());
                    Student student = studentDao.selectOne(studentQueryWrapper);
                    Course course = courseDao.selectOne(courseQueryWrapper);
                    //拷贝属性
                    BeanUtils.copyProperties(xuanKe, xuanKeDto);
                    //判断学生对象是否为空
                    if (student != null) {
                        xuanKeDto.setSName(student.getSName());
                        xuanKeDto.setDengJi(student.getDengJi());
                        classQueryWrapper.eq("cls_no", student.getClsNo());
                        Class aClass1 = classDao.selectOne(classQueryWrapper);
                        if (aClass1 != null) {
                            xuanKeDto.setSClass(aClass1.getClsName());
                        }
                    }
                    //判断课程对象是否为空
                    if (course != null) {
                        xuanKeDto.setCName(course.getCName());
                    }
                    if (xuanKe.getCGrade() == null) {
                        xuanKeDto.setCGrade("暂无成绩");
                    } else {
                        if (xuanKe.getCGrade().trim().length() == 0) {
                            xuanKeDto.setCGrade("暂无成绩");
                        }
                    }

                    //清空查询条件
                    studentQueryWrapper.clear();
                    classQueryWrapper.clear();
                    courseQueryWrapper.clear();
                    //添加教师信息到数组
                    cds.add(xuanKeDto);
                    //重新开辟内存地址
                    xuanKeDto = new XuanKeDto();
                }
                return new PageResult<XuanKeDto>(cds, xuanKes.getTotal());
            }
        }
        return null;
    }

    /**
     * 查询未安排课程教师信息
     *
     * @return 教师信息列表
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public List<TeacherDto> noCnoList() {
        QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("t_no", "t_name", "t_sex", "id", "t_age", "entry_year", "c_no");
        // 根据编号降序排序
        queryWrapper.orderByDesc("t_no");
        List<Teacher> teachers = teacherDao.selectList(queryWrapper);
        List<TeacherDto> list = new ArrayList<>();
        for (Teacher teacher : teachers) {
            TeacherDto teacherDto = new TeacherDto();
            if (teacher.getCNo() != null) {
                if (teacher.getCNo().trim().length() == 0) {
                    BeanUtils.copyProperties(teacher, teacherDto);
                    list.add(teacherDto);
                } else {
                    QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
                    courseQueryWrapper.eq("c_no", teacher.getCNo());
                    Course course = courseDao.selectOne(courseQueryWrapper);
                    if (course == null) {
                        BeanUtils.copyProperties(teacher, teacherDto);
                        list.add(teacherDto);
                    }
                    courseQueryWrapper.clear();
                }
            } else {
                BeanUtils.copyProperties(teacher, teacherDto);
                list.add(teacherDto);
            }

        }
        return list;
    }

    /**
     * 查询未安排班级教师信息
     *
     * @return 教师信息列表
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public List<TeacherDto> noClsNoList() {
        QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("t_no", "t_name", "t_sex", "id", "t_age", "entry_year", "cls_no");
        // 根据编号降序排序
        queryWrapper.orderByDesc("t_no");
        List<Teacher> teachers = teacherDao.selectList(queryWrapper);
        List<TeacherDto> list = new ArrayList<>();
        for (Teacher teacher : teachers) {
            TeacherDto teacherDto = new TeacherDto();
            if (teacher.getClsNo() != null) {
                if (teacher.getClsNo().trim().length() == 0) {
                    BeanUtils.copyProperties(teacher, teacherDto);
                    list.add(teacherDto);
                } else {
                    QueryWrapper<Class> classQueryWrapper = new QueryWrapper<>();
                    classQueryWrapper.eq("cls_no", teacher.getClsNo());
                    Class aclass = classDao.selectOne(classQueryWrapper);
                    if (aclass == null) {
                        BeanUtils.copyProperties(teacher, teacherDto);
                        list.add(teacherDto);
                    }
                    classQueryWrapper.clear();
                }
            } else {
                BeanUtils.copyProperties(teacher, teacherDto);
                list.add(teacherDto);
            }

        }
        return list;
    }

    /**
     * 查询自己所教授的课程信息
     */
    @Override
    public PageResult<CourseDto> myCourse(Integer page, Integer size, Map<String, Object> formMap) {
        QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
        // 构建查询条件
        if (formMap != null) {
            String tNo = formMap.get("tNo").toString();
            teacherQueryWrapper.eq("t_no", tNo);
            Teacher teacher = teacherDao.selectOne(teacherQueryWrapper);
            if (teacher != null) {
                //查询课层表字段
                courseQueryWrapper.eq("c_no", teacher.getCNo());
                courseQueryWrapper.select("c_no", "c_name", "type", "id", "kind", "deng_ji");
                Page<Course> coursePage = courseDao.selectPage(new Page<Course>(page, size), courseQueryWrapper);
                List<CourseDto> cds = new ArrayList<>();
                CourseDto courseDto = new CourseDto();

                for (Course course : coursePage.getRecords()) {
                    //拷贝属性
                    BeanUtils.copyProperties(course, courseDto);
                    cds.add(courseDto);
                    //重新开辟内存地址
                    courseDto = new CourseDto();
                }
                return new PageResult<CourseDto>(cds, coursePage.getTotal());
            }
        }
        return null;
    }

    /**
     * 查询自己所管理的班级信息
     */
    @Override
    public PageResult<ClassDto> myClass(Integer page, Integer size, Map<String, Object> formMap) {
        QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Class> classQueryWrapper = new QueryWrapper<>();
        // 构建查询条件
        if (formMap != null) {
            String tNo = formMap.get("tNo").toString();
            teacherQueryWrapper.eq("t_no", tNo);
            Teacher teacher = teacherDao.selectOne(teacherQueryWrapper);
            if (teacher != null) {
                //查询班级表字段
                classQueryWrapper.eq("cls_no", teacher.getClsNo());
                classQueryWrapper.select("cls_no", "cls_name", "major", "id");
                Page<Class> classPage = classDao.selectPage(new Page<Class>(page, size), classQueryWrapper);
                List<ClassDto> cds = new ArrayList<>();
                ClassDto classDto = new ClassDto();

                for (Class aClass : classPage.getRecords()) {
                    //拷贝属性
                    BeanUtils.copyProperties(aClass, classDto);
                    classDto.setTName(teacher.getTName());
                    cds.add(classDto);
                    //重新开辟内存地址
                    classDto = new ClassDto();
                }
                return new PageResult<ClassDto>(cds, classPage.getTotal());
            }
        }
        return null;
    }

    /**
     * 添加学生成绩
     *
     * @param grade 成绩信息
     * @return 结果
     */
    @Override
    public int addGrade(Grade grade) {
        try {
            if (grade != null) {
                if (Integer.valueOf(grade.getGrade()) < 0 || Integer.valueOf(grade.getGrade()) > 100) {
                    throw new MyRuntimeException("添加的成绩应该在在0~100之间！！");
                } else {
                    XuanKe xuanKe = new XuanKe();
                    xuanKe.setId(Integer.valueOf(grade.getId()));
                    xuanKe.setCGrade(grade.getGrade());
                    return xuanKeDao.updateById(xuanKe);
                }
            }
        } catch (Exception e) {
            throw new MyRuntimeException(e.getMessage());
        }
        return 0;
    }

    /**
     * 根据选课id查询学生成绩
     */
    @Override
    public Grade getGradeById(String id) {
        try {
            if (id != null) {
                Integer integer = Integer.valueOf(id);
                XuanKe xuanKe = xuanKeDao.selectById(integer);
                if (xuanKe != null) {
                    Grade grade = new Grade();
                    grade.setGrade(xuanKe.getCGrade());
                    return grade;
                }
            }
        } catch (Exception e) {
            throw new MyRuntimeException("系统错误");
        }
        return null;
    }

    /**
     * 查询自己所管理的班级学生信息
     */
    @Override
    public PageResult<StudentDto> myStudent(Integer page, Integer size, Map<String, Object> formMap) {
        QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
        // 构建查询条件
        if (formMap != null) {
            String tNo = formMap.get("tNo").toString();
            teacherQueryWrapper.eq("t_no", tNo);
            Teacher teacher = teacherDao.selectOne(teacherQueryWrapper);
            if (teacher != null) {
                //查询班级表字段
                studentQueryWrapper.eq("cls_no", teacher.getClsNo());
                studentQueryWrapper.select("s_no", "s_name", "s_sex", "s_age", "graduation_year");
                Page<Student> studentPage = studentDao.selectPage(new Page<Student>(page, size), studentQueryWrapper);
                List<StudentDto> cds = new ArrayList<>();
                StudentDto studentDto = new StudentDto();

                for (Student student : studentPage.getRecords()) {
                    //拷贝属性
                    BeanUtils.copyProperties(student, studentDto);
                    cds.add(studentDto);
                    //重新开辟内存地址
                    studentDto = new StudentDto();
                }
                return new PageResult<StudentDto>(cds, studentPage.getTotal());
            }
        }
        return null;
    }
}



